﻿using System.Collections.Generic;
using DataFiller.DataStorage.Extension;
using DataFiller.DataStorage.Extension.Excel.Holders;
using DataFiller.DataStorage.Extension.Excel.Locaters;
using DataFiller.DataStorage.Extension.ExcelOperator;
using DataFiller.DataStorage.Regions;
using NPOI.SS.UserModel;
using NPOI.SS.Util;

namespace DataFiller.ExportWithNpoi
{
    public class NSheet : IExcelSheet
    {
        public string SheetName
        {
            get
            {
                return _sheet.SheetName;
            }
        }
        public int RegionCount
        {
            get
            {
                return _sheet.NumMergedRegions;
            }
        }

        private ISheet _sheet;
        List<CellRangeAddressBase> _regions;

        public NSheet(ISheet sheet)
        {
            this._sheet = sheet;

            if (this._sheet.NumMergedRegions > 0)
            {
                _regions = new List<CellRangeAddressBase>();
                for (int index = 0; index < this._sheet.NumMergedRegions; index++)
                    _regions.Add(this._sheet.GetMergedRegion(index));
            }

        }

        #region IExcelSheet

        public void SheetHandler(IExcelbook templateBook, ExportContext context)
        {
            //todo improve maintainability
            templateBook.RemoveSheetByName(this.SheetName);
            IExcelSheet newSheet = templateBook.CreateSheet(this.SheetName);

            if (this._regions != null && this._regions.Count > 0)
            {
                foreach (var region in _regions)
                {
                    newSheet.CopyRegion(region);
                }
            }

            List<IDataRegion<int>> regions = context.DataMap.GetRegions();
            foreach (var region in regions)
            {
                foreach (ExcelHolder dsCell in region.Records)
                {
                    ExcelLocater locater = (ExcelLocater)dsCell.Locater;

                    var newRow = newSheet.GetOrCreateRowByIndex(locater.RowNumber);
                    var newCell = newRow.GetOrCreateColByIndex(locater.ColNumber);

                    newCell.SetCellValue(dsCell);
                    newCell.CellStyle = (ICellStyle)dsCell.Style;
                }
            }

            context.DataMap.ClearRegion();
        }
        public IExcelRow GetOrCreateRowByIndex(int rownumber)
        {
            IRow tempRow = _sheet.GetRow(rownumber);
            return tempRow == null ?
                new NRow(_sheet.CreateRow(rownumber)) :
                new NRow(tempRow);
        }
        public IEnumerator<IExcelRow> GetEnumerator()
        {
            foreach (IRow row in _sheet)
                yield return new NRow(row);
        }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
        public IExcelRow GetRow(int rowNumber)
        {
            IRow tempRow = _sheet.GetRow(rowNumber);
            return tempRow == null ?
                null :
                new NRow(tempRow);
        }
        public IExcelRow CreateRow(int rowNumber)
        {
            return new NRow(_sheet.CreateRow(rowNumber));
        }
        public void CopyRegion(object region)
        {
            this._sheet.AddMergedRegion((CellRangeAddress)region);
        }
        #endregion
    }
}
